package com.liziyi0914.morearmor.event;

import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 2021/6/27<br>
 * MoreArmor<br>
 *
 * @author huanmeng_qwq
 */
public class EventManager {
    private static final Multimap<Object, Method> listenerMethod = LinkedHashMultimap.create();

    @SuppressWarnings("UnusedReturnValue")
    public static <T extends Event> T call(T e) {
        listenerMethod.entries().stream().filter(entry -> {
            return entry.getValue().getParameterTypes()[0].isInstance(e);
        }).forEach(entry -> {
            try {
                entry.getValue().invoke(entry.getKey(), e);
            } catch (IllegalAccessException | InvocationTargetException illegalAccessException) {
                illegalAccessException.printStackTrace();
            }
        });
        return e;
    }

    public static void registerListener(IListener obj) {
        for (Method method : obj.getClass().getMethods()) {
            if (method.getParameterCount() == 1 && Event.class.isAssignableFrom(method.getParameterTypes()[0])&&method.isAnnotationPresent(Listener.class)) {
                listenerMethod.put(obj, method);
            }
        }
    }

    public static void unregisterListener(IListener obj) {
        listenerMethod.removeAll(obj);
    }

    public static void unregisterListener(Class<?> clazz) {
        List<IListener> objs = new ArrayList<>();
        for (Object o : listenerMethod.keySet()) {
            if (!(o instanceof IListener)) {
                continue;
            }
            if (clazz.isAssignableFrom(o.getClass())) {
                objs.add((IListener) o);
            }
        }
        objs.forEach(EventManager::unregisterListener);
    }
}
